#pragma once
#include<iostream>
#include<vector>
#include<queue>
#include"Thread.hpp"
#include"LockGuard.hpp"
#include"Task.hpp"

using namespace std;

const int g_thread_num=3;
template <class T>
class ThreadPool
{
private:
    ThreadPool(int thread_num=g_thread_num)
    :_num(thread_num)
    {
        pthread_mutex_init(&_lock,nullptr);
        pthread_cond_init(&_cond,nullptr);
        for(int i=0;i<_num;i++)
        {
            //这样可以使得这个工作函数顺利地访问类内的成员变量和成员函数
            _threads.push_back(new Thread(i,worker,this));
        }
    }
    ThreadPool(const ThreadPool<T>& other)=delete;
    ThreadPool<T>& operator=(const ThreadPool<T>& other)=delete;
public:
    pthread_mutex_t* getMutex()
    {
        return &_lock;
    }
    bool isEmpty()
    {
        return _task_queue.empty();
    }
    void waitCond()
    {
        pthread_wait_cond(&_cond,&_lock);
    }
    T getTask()
    {
        T task=_task_queue.front();
        _task_queue.pop();
        return task;
    }
    void pushTask(const T& task)
    {
        lockGuard lockguard(&_lock);
        _task_queue.push(task);
        pthread_cond_signal(&_cond);
    }
    static void* worker(void* args)
    {
        ThreadData* td=static_cast<ThreadData*>(args);
        ThreadPool<T>* tp=static_cast<ThreadPool*>(td->_args);
        while(true)
        {
            T task;
            {
                LockGuard lockguard(&_lock);
                while(tp->isEmpty())
                {
                    tp->waitCond();
                }
                task=tp->getTask();
            }
            task(td->_name);
        }
    }
private:
    int _num;
    vector<Thread*> _threads;
    queue<T> _task_queue;
    pthread_mutex_t _lock;
    pthread_cond_t _cond;
};
// #pragma once
// #include<iostream>
// #include<string>

// using namespace std;
// typedef void*(*func_t)(void*);

// class ThreadData
// {
// public:
//     string _name;
//     void* _args;
// };
// class Thread
// {
// public:
//     Thread(int num,func_t callbacks,void* args)
//     :_func(callbacks)
//     {
//         char namebuffer[1024];
//         snprintf(namebuffer,sizeof(namebuffer),"Thread-%d",num);
//         _name=namebuffer;
//         _tdata._args=args;
//         _tdata._name=_name;
//     }
//     void start()
//     {
//         pthread_create(&_tid,nullptr,_func,(void*)&_tdata);
//     }
//     void join()
//     {
//         pthread_join(_tid,nullptr);
//     }
//     ~Thread()
//     {

//     }
// private:
//     string _name;
//     func_t _func;
//     ThreadData _tdata;
//     pthread_t _tid;
// };
// typedef void*(*func_t)(void*);

// class ThreadData
// {
// public:
//     string _name;
//     void* _args;
// };

// class Thread
// {
// public:
//     Thread(int num,func_t callbacks,void* args)
//     {
//         //构造函数为每个线程进行初始化操作
//         char namebuffer[1024];
//         snprintf(namebuffer,sizeof(namebuffer),"Thread-%d",num);
//         _name=namebuffer;
//         _tdata._args=args;
//         _tdata._name=namebuffer;
//     }
//     void start()
//     {
//         pthread_create(&_tid,nullptr,_func,(void*)&_tdata);
//     }
//     void join()
//     {
//         pthread_join(_tid,nullptr);
//     }
//     ~Thread()
//     {

//     }
// private:
//     ThreadData _tdata;
//     string _name;
//     pthread_t _tid;
//     func_t _func;
// };